/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.eleric.rememome.db;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import com.eleric.rememome.db.factory.DbRetrieverFactory;
import com.eleric.rememome.memo.Memo;
import com.eleric.rememome.memo.MemoCategory;
import java.util.List;

/**
 *
 * @author MWaldman
 */
public class DatabaseHelper extends SQLiteOpenHelper
{

    private DbRetrieverFactory<Memo> dbRetrieveFactoryMemo;
    private DbRetrieverFactory<MemoCategory> dbRetrieveFactoryMemoCategory;

    public DatabaseHelper(Context context, String name, int version,
            DbRetrieverFactory<Memo> dbRetrieveFactoryMemo,
            DbRetrieverFactory<MemoCategory> dbRetrieveFactoryMemoCategory)
    {
        super(context, name, null, version);
        this.dbRetrieveFactoryMemo = dbRetrieveFactoryMemo;
        this.dbRetrieveFactoryMemoCategory = dbRetrieveFactoryMemoCategory;
    }

    @Override
    public void onCreate(SQLiteDatabase db)
    {
        // Create memo table
        db.execSQL(dbRetrieveFactoryMemo.getCurrentVersionDbRetriever().createTableSQL());
        // Initialize memo table if it needs initializing
        runSqlArray(db, dbRetrieveFactoryMemo.getCurrentVersionDbRetriever().initializeTableSQL());
        // Create category table then fill with with default categories
        db.execSQL(dbRetrieveFactoryMemoCategory.getCurrentVersionDbRetriever().createTableSQL());
        // Initialize category table if it needs initializing
        runSqlArray(db, dbRetrieveFactoryMemoCategory.getCurrentVersionDbRetriever().
                initializeTableSQL());
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
    {
        DbRetrieverFactory dbRetrieveFactory;
        // Remove restraints
        runSqlArray(db, dbRetrieveFactoryMemoCategory.getCurrentVersionDbRetriever().
                removeTableRestraintsSQL());
        runSqlArray(db, dbRetrieveFactoryMemo.getCurrentVersionDbRetriever().
                removeTableRestraintsSQL());

        // Copy Category if new version
        transformTable(db, dbRetrieveFactoryMemoCategory, newVersion);

        // Copy Memo if new version
        transformTable(db, dbRetrieveFactoryMemo, newVersion);


        // Build restraints
        runSqlArray(db, dbRetrieveFactoryMemoCategory.getCurrentVersionDbRetriever().
                buildTableRestraintsSQL());
        runSqlArray(db,
                dbRetrieveFactoryMemo.getCurrentVersionDbRetriever().buildTableRestraintsSQL());
    }

    private void transformTable(SQLiteDatabase db, DbRetrieverFactory dbRetrieveFactory,
            int newVersion)
    {
        if (dbRetrieveFactory.getCurrentVersionDbRetriever().getVersion() >= newVersion)
        {
            // Rename old table
            renameTable(db, dbRetrieveFactory.getCurrentVersionDbRetriever().getTable(),
                    dbRetrieveFactory.getPreviousVersionDbRetriever().
                    getTable());
            // Create new table
            db.execSQL(dbRetrieveFactory.getCurrentVersionDbRetriever().createTableSQL());
            // Copy data from old to new table
            transfer(db, dbRetrieveFactory);
            // Remove old version of table
            db.execSQL("DROP TABLE IF EXISTS " + dbRetrieveFactory.getPreviousVersionDbRetriever().
                    getTable() + " ");
        }
    }

    private void transfer(SQLiteDatabase db, DbRetrieverFactory dbRetrieverFactory)
    {
        List prevList;
        prevList = dbRetrieverFactory.getPreviousVersionDbRetriever().list(db);
        for (Object o : prevList)
        {
            dbRetrieverFactory.getCurrentVersionDbRetriever().insert(o, db);
        }
    }

    private void runSqlArray(SQLiteDatabase db, String[] sql)
    {
        if (sql != null)
        {
            for (String init : sql)
            {
                db.execSQL(init);
            }
        }
    }

    private void renameTable(SQLiteDatabase db, String fromTable, String toTable)
    {
        String query = "alter table " + fromTable + " " +
                "rename to " + toTable + "; ";
        db.execSQL(query);

    }
}
